#!/usr/bin/python
#-*- coding:UTF-8 -*-
'''
/*
A tornado static http server
*/
Requirement: tornado
'''

import sys
import os
import zipfile
import socket
import hashlib
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

ROOT=""
HOSTCODE="UTF-8"
CHECKLOGIN=True

HEADTEMPLATE="""<html><head>
<script language="javascript">
var currpos,timer;
function init(){timer=setInterval ("scrollwindow()",10);}
function clearr(){clearInterval(timer);}
function scrollwindow(){currpos=document.body.scrollTop;window.scroll(0,++currpos);
if(currpos !=document.body.scrollTop)
clearr();}
document.onmousedown=clearr
document.ondblclick=init
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/></head><body>
"""

def CheckPasswd(passwd, hashpass):
    s = hashlib.sha256()
    p = hashpass[:2]+passwd
    s.update(p)
    return hashpass[2:]==s.hexdigest()

def CheckLogin(self):
    global CHECKLOGIN
    if not CHECKLOGIN:
        return True
    auth_header = self.request.headers.get('Authorization', None)
    if auth_header is not None:
        auth_mode, auth_base64 = auth_header.split(' ', 1)
        auth_username, auth_password = auth_base64.decode('base64').split(':', 1)
        if auth_username=="admin" and CheckPasswd(auth_password,"x$9a808243ff06b8803ff374a681d553e2498c24291730a2a4c752e21bc7b67a2e"):
            return True
    self.set_header('Access-Control-Allow-Origin', '*')
    self.set_header('WWW-Authenticate', 'Basic realm="Authentication required"')
    self.set_status(401)
    return False

class ZipHandler(tornado.web.RequestHandler):
    def get(self, r):
        if not CheckLogin(self):
            return None
        ret = HEADTEMPLATE+"""<table>"""
        f = os.path.join(ROOT,r)
        z = zipfile.ZipFile(f,"r")
        for n in z.namelist():
            ret += "<tr><td><a href='/"+r+"/"+n+"'>"+n+"</a></td></tr>\n"
        ret +="</table></body></html>"
        self.write(ret)

class ZipTextHandler(tornado.web.RequestHandler):
    def get(self, r, n):
        if not CheckLogin(self):
            return None
        f = os.path.join(ROOT,r)
        z = zipfile.ZipFile(f,"r")
        f = z.read(n)
        charset = chardet.detect(f)
        content_type = "text/plain; charset=%s"%charset["encoding"]
        self.set_header("Content-Type", content_type)
        self.write(f)

class TestHandler(tornado.web.RequestHandler):
    def get(self):
        ret = os.getcwd()
        self.write(ret)

class TextFileHandler(tornado.web.StaticFileHandler):
    def set_extra_headers(self, path):
        f = open(os.path.join(ROOT,path)).read()
        charset = chardet.detect(f)
        content_type = "text/plain; charset=%s"%charset["encoding"]
        self.set_header("Content-Type", content_type)

class Application(tornado.web.Application):
    def __init__(self):
        settings = dict(
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), ROOT),
            xsrf_cookies=True,
            cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
            login_url="/auth/login",
            autoescape=None,
        )
        handlers = [
            (r"/(.*\.zip)", ZipHandler),
            (r"/(.*\.zip)/(.*)", ZipTextHandler),
            (r"/(.*\.txt)", TextFileHandler, dict(path=settings['static_path'])),
            (r"/(.*)", tornado.web.StaticFileHandler, dict(path=settings['static_path'])),
        ]
        tornado.web.Application.__init__(self, handlers, **settings)

def main():
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(Application())
    http_server.listen(80)
    tornado.ioloop.IOLoop.instance().start()


if __name__ == "__main__":
    ips = socket.gethostbyname_ex(socket.gethostname())
    for ip in ips[2]:
        print ip
    if len(sys.argv) >= 2:
        ROOT = sys.argv[1]
    else:
        ROOT = raw_input("Specify the root directory: ")
    if len(sys.argv) >= 3:
        HOSTCODE = sys.argv[2]
    print HOSTCODE
    if len(sys.argv) >=4:
        CHECKLOGIN=eval(sys.argv[3])
    main()

